package com.bootdo.netty.hander;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.config.ApplicationContextRegister;
import com.bootdo.common.redisUtils.JedisUtils;
import com.bootdo.common.utils.DateUtils;
import com.bootdo.common.utils.R;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.haojiangboutils.MapBuild;
import com.bootdo.kaoqin.domain.KaoqinConfig;
import com.bootdo.kaoqin.domain.KaoqinOrder;
import com.bootdo.kaoqin.domain.KaoqinUser;
import com.bootdo.kaoqin.queue.CallWorkQueue;
import com.bootdo.kaoqin.service.KaoqinConfigService;
import com.bootdo.kaoqin.service.KaoqinOrderService;
import com.bootdo.kaoqin.service.KaoqinUserService;
import com.bootdo.kaoqin.service.impl.KaoqinConfigServiceImpl;
import com.bootdo.kaoqin.service.impl.KaoqinOrderServiceImpl;
import com.bootdo.kaoqin.service.impl.KaoqinUserServiceImpl;
import com.bootdo.netty.common.CtxRefList;
import com.bootdo.netty.model.SmartCarProtocol;
import com.bootdo.redis.RedisUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.util.Date;
import java.util.List;
import java.util.Map;

public class ServerHandler extends ChannelInboundHandlerAdapter {
   private static   KaoqinUserService kaoqinUserService ;
    private static   RedisUtil redisUtil ;
    private static   KaoqinConfigService kaoqinConfigService ;
    // 用于获取客户端发送的信息
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
             {
        // 用于获取客户端发来的数据信息
        SmartCarProtocol body = (SmartCarProtocol) msg;
        String message = body.getMessage();
        ReferenceCountUtil.release(msg);


        JSONObject j = new JSONObject();
        j.put("code", 9);
        String str = j.toJSONString();



        System.err.println("Server接受的客户端的信息 :" + message);
         String key ="";
        if(StringUtils.isNotEmpty(message)){
           try{
               JSONObject jsonObject = (JSONObject) JSONObject.parse(message);
               key =   jsonObject.getString("userName");
               if(!CtxRefList.CHANNEIDKEY.containsKey(ctx.channel().id().asShortText())){
                   CtxRefList.CHANNEIDKEY.put(ctx.channel().id().asShortText(),key);
                   CtxRefList.CXTREF.put(key, ctx.channel());
               }
               if(jsonObject.containsKey("type")){
                   int type = jsonObject.getIntValue("type");
                     kaoqinUserService = kaoqinUserService == null ?  ApplicationContextRegister.getBean(KaoqinUserServiceImpl.class) : kaoqinUserService;
                     redisUtil = redisUtil  == null ?  ApplicationContextRegister.getBean(RedisUtil.class) : redisUtil;
                     kaoqinConfigService = kaoqinConfigService == null ? ApplicationContextRegister.getBean(KaoqinConfigServiceImpl.class) : kaoqinConfigService;


                     if(null != kaoqinUserService && type == 2){
                       if(!StringUtils.isEmpty(key)){
                           List<KaoqinUser> list = kaoqinUserService.list(MapBuild.getInstand().setKV("userName",key));
                           list.stream().forEach(item ->{
                               List<KaoqinConfig> configs = kaoqinConfigService.list(MapBuild.getInstand().setKV("groupId", item.getGroupId()));
                               item.setConfigs(configs);
                           });
                           /* JSONArray jsonArray = (JSONArray) JSONArray.toJSON(list);*/
                           String r = JSONObject.toJSONString(R.ok(200, "ok").put("l", list));
                           SmartCarProtocol response = new SmartCarProtocol(r.getBytes().length,
                                   r.getBytes());
                           ctx.writeAndFlush(response);
                           return;
                       }
                   }else if(null != redisUtil && null != kaoqinUserService && type == 9){
                       String v = jsonObject.getString("v");
                       int last =  v.lastIndexOf("_");
                       if(last > 0){
                           v = v.substring(last+1, v.length());
                       }
                       KaoqinUser kaoqinUser = kaoqinUserService.get(Long.parseLong(v));
                       if(null != kaoqinUser && null == redisUtil.get(kaoqinUser.getId()+"__CATCH")){
                           CallWorkQueue.kaoqinUserLinkedBlockingQueue.add(kaoqinUser);
                           redisUtil.set(kaoqinUser.getId()+"__CATCH", "OK",10);
                       }
                       String r = JSONObject.toJSONString(R.ok(300,"打卡成功"));
                       SmartCarProtocol response = new SmartCarProtocol(r.getBytes().length,
                               r.getBytes());
                       ctx.writeAndFlush(response);
                       return;
                   }
               }
           }catch (Exception e){
               str = e.getMessage();
           }
        }
        String r = JSONObject.toJSONString(R.ok(0,"OK"));
        // 会写数据给客户端
        SmartCarProtocol response = new SmartCarProtocol(r.getBytes().length,
                r.getBytes());
        // 当服务端完成写操作后，关闭与客户端的连接
        ctx.writeAndFlush(response);
        // .addListener(ChannelFutureListener.CLOSE);
        // 当有写操作时，不需要手动释放msg的引用
        // 当只有读操作时，才需要手动释放msg的引用
        // 将原消息转化为新的消息并调用 ctx.fireChannelRead(newMsg)往下传，那必须把原消息release掉。
        //  释放消息   ReferenceCountUtil.release(msg);

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // cause.printStackTrace();
        /**
         * 释放change 并删除掉 map对应关系
         */
        if(CtxRefList.CHANNEIDKEY.containsKey(ctx.channel().id().asShortText())){
            CtxRefList.CXTREF.remove(CtxRefList.CHANNEIDKEY.get(ctx.channel().id().asShortText()));
        }
        ctx.close();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        /**
         * 释放change 并删除掉 map对应关系
         */
        if(CtxRefList.CHANNEIDKEY.containsKey(ctx.channel().id().asShortText())){
            CtxRefList.CXTREF.remove(CtxRefList.CHANNEIDKEY.get(ctx.channel().id().asShortText()));
        }
        super.channelUnregistered(ctx);
    }


}
